﻿using OA.Infrastructure.WeCom.Abstractions;
using OA.Infrastructure.WeCom.Serializers.Abstractions;
using OA.Infrastructure.WeCom.Serializers.Attributes;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;

namespace OA.Infrastructure.WeCom;

public class WeComMessageDispatcher : IWeComMessageDispatcher
{
    public enum MessageType : byte
    {
        Event = 1
    }

    private XmlNode _root = null!;
    private MessageType _messageType;
    private readonly IServiceProvider _serviceProvider;

    public WeComMessageDispatcher(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public WeComMessageDispatcher Dispatch(string msg)
    {
        var xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(msg);

        var root = xmlDoc.SelectSingleNode("xml");
        if (root is null)
        {
            throw new NotImplementedException("未实现对应的企业微信消息协议");
        }

        _root = root;

        var msgTypeNode = _root.SelectSingleNode("MsgType");

        if (msgTypeNode is null)
        {
            throw new NotImplementedException("未实现对应的企业微信消息协议");
        }

        _messageType = msgTypeNode.InnerText switch
        {
            "event" => MessageType.Event,
            _ => throw new NotImplementedException("未实现对应的企业微信消息协议"),
        };

        return this;
    }

    public MessageType GetMessageType() => _messageType;

    public bool TryGetSerializer(out XmlSerializer serializer)
    {
        serializer = _messageType switch
        {
            MessageType.Event => GetEventSerializer(),
            _ => throw new NotImplementedException("未实现对应的企业微信消息协议解析器"),
        };

        return serializer is not null;
    }

    private XmlSerializer GetEventSerializer()
    {
        var evNode = _root.SelectSingleNode("Event");

        if (evNode is null)
        {
            throw new InvalidOperationException("不符合标准的企业微信消息协议");
        }

        var evContent = evNode.InnerText;


        return _serviceProvider
            .GetServices<IWeComMessageSerializable>()
            .Where(x => x.GetType().GetCustomAttribute<EventTypeAttribute>() != null)
            .FirstOrDefault(x => x.GetType().GetCustomAttribute<EventTypeAttribute>()!.EventType == evContent) is not XmlSerializer serializer
                ? throw new NotImplementedException("未注册相应的事件处理程序")
                : serializer;
    }
}